package firewing.datastore;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;

import firewing.object.Dict.TrendSource;
import firewing.object.Trend;

public class TrendStore {
	private static final Logger log = Logger.getLogger(TrendStore.class
			.getName());

	private static ArrayList<Trend> _cache;

	private static DatastoreService _datastore = DatastoreServiceFactory
			.getDatastoreService();

	public static ArrayList<Trend> get(String s) {
		try {
			Query query = new Query("Trends");
			query.addFilter("phrase", FilterOperator.EQUAL, s);

			List<Entity> result = _datastore.prepare(query).asList(
					FetchOptions.Builder.withDefaults());

			if (result != null) {
				ArrayList<Trend> ret = new ArrayList<Trend>();

				for (Entity e : result) {
					Trend t = new Trend();
					// -------common-----------
					t.setSource(TrendSource.load((String) e.getProperty("source")));
					t.setPhrase((String) e.getProperty("phrase"));
					t.setRank((Integer) e.getProperty("ranking"));
					t.setBidEstimation((Boolean) e.getProperty("bidEstimation"));

					// ----------from Google Trends--------
					if (t.getSource().equals("GoogleTrends")) {
						t.setHotness((String) e.getProperty("hotness"));
						t.setPeak((String) e.getProperty("peak"));
						t.setLocation((String) e.getProperty("location"));
						t.setRelatedSearch((String) e
								.getProperty("relatedSearch"));
					}

					// -----------from Yahoo Buzz----------
					if (t.getSource().equals("YahooBuzz")) {
						t.setPrevRank((Integer) e.getProperty("prevRank"));
						t.setDaysOnChart((Integer) e.getProperty("daysOnChart"));
						t.setYahooBuzzMove((String) e
								.getProperty("yahooBuzzMove"));
						t.setYahooBuzzScore((Integer) e
								.getProperty("yahooBuzzScore"));
						t.setYahooBuzzOneDayMove((String) e
								.getProperty("yahooBuzzOneDayMove"));
					}

					// ----------from Google AdWords API--------
					if (t.hasBidEstimation()) {
						t.setAverageCPC((Double) e.getProperty("averageCPC"));
						t.setDailyClick((Double) e.getProperty("dailyClick"));
						t.setDailyCost((Double) e.getProperty("dailyCost"));
						t.setBidPosition((Double) e.getProperty("bidPosition"));
					}
					ret.add(t);
				}
				log.info("Load trend cache finished");
				return ret;
			} else {
				log.warning("Query for trend datastore returned nothing");
				return null;
			}
			// if (_cache == null) {
			// load();
			// }
			//
			// synchronized (_cache) {
			// return (Trend) _cache.get(s);
			// }

		} catch (Exception e) {
			e.printStackTrace();
			log.severe("Get from datastore failed");
			return null;
		}
	}

	public static void put(Trend t) {
		try {
			// if (_cache == null) {
			// load();
			// }
			//
			// // update local cache
			// synchronized (_cache) {
			// _cache.put(t.getPhrase(), t);
			// }

			// update datastore
			Entity trendEntity = new Entity("Trends");
			// -------common----------
			trendEntity.setProperty("source", t.getSource().toString());
			trendEntity.setProperty("phrase", t.getPhrase());
			trendEntity.setProperty("rank", t.getRank());

			// --------from Google Trends---------
			if (t.getSource() == TrendSource.GoogleTrends) {
				trendEntity.setProperty("hotness", t.getHotness());
				trendEntity.setProperty("peak", t.getPeak());
				trendEntity.setProperty("relatedSearch", t.getRelatedSearch());
				trendEntity.setProperty("location", t.getLocation());
			}

			// ---------from Yahoo Buzz---------
			if (t.getSource() == TrendSource.YahooBuzz) {
				trendEntity.setProperty("prevRank", t.getPrevRank());
				trendEntity.setProperty("daysOnChart", t.getDaysOnChart());
				trendEntity.setProperty("yahooBuzzMove", t.getYahooBuzzMove());
				trendEntity
						.setProperty("yahooBuzzScore", t.getYahooBuzzScore());
				trendEntity.setProperty("yahooBuzzOneDayMove",
						t.getYahooBuzzOneDayMove());
			}

			// ---------from Google AdWords API-----------
			if (t.hasBidEstimation()) {
				trendEntity.setProperty("averageCPC", t.getAverageCPC());
				trendEntity.setProperty("dailyClick", t.getDailyClick());
				trendEntity.setProperty("dailyCost", t.getDailyCost());
				trendEntity.setProperty("bidPosition", t.getBidPosition());
			}

			_datastore.put(trendEntity);

			log.info("Put to datastore finished");
		} catch (Exception e) {
			e.printStackTrace();

			log.severe("Put to datastore failed");
		}
	}

	public static ArrayList<Trend> getAll() {
		if (_cache != null) {
			return _cache;
		}

		_cache = new ArrayList<Trend>();
		try {
			// load from datastore
			Query query = new Query("Trends");
			// result could be huge
			List<Entity> result = _datastore.prepare(query).asList(
					FetchOptions.Builder.withDefaults());

			if (result != null) {
				for (Entity e : result) {
					Trend t = new Trend();
					// -------common-----------
					t.setSource(TrendSource.load((String) e.getProperty("source")));
					t.setPhrase((String) e.getProperty("phrase"));
					t.setRank((Integer) e.getProperty("ranking"));
					t.setBidEstimation((Boolean) e.getProperty("bidEstimation"));

					// ----------from Google Trends--------
					if (t.getSource().equals("GoogleTrends")) {
						t.setHotness((String) e.getProperty("hotness"));
						t.setPeak((String) e.getProperty("peak"));
						t.setLocation((String) e.getProperty("location"));
						t.setRelatedSearch((String) e
								.getProperty("relatedSearch"));
					}

					// -----------from Yahoo Buzz----------
					if (t.getSource().equals("YahooBuzz")) {
						t.setPrevRank((Integer) e.getProperty("prevRank"));
						t.setDaysOnChart((Integer) e.getProperty("daysOnChart"));
						t.setYahooBuzzMove((String) e
								.getProperty("yahooBuzzMove"));
						t.setYahooBuzzScore((Integer) e
								.getProperty("yahooBuzzScore"));
						t.setYahooBuzzOneDayMove((String) e
								.getProperty("yahooBuzzOneDayMove"));
					}

					// ----------from Google AdWords API--------
					if (t.hasBidEstimation()) {
						t.setAverageCPC((Double) e.getProperty("averageCPC"));
						t.setDailyClick((Double) e.getProperty("dailyClick"));
						t.setDailyCost((Double) e.getProperty("dailyCost"));
						t.setBidPosition((Double) e.getProperty("bidPosition"));
					}
					_cache.add(t);
				}

				return _cache;
			} else {
				log.warning("Query for trend datastore returned nothing");
				return null;
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.severe("Load trend cache failed");
			return null;
		}
	}
}
